﻿#region imports

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Web;
using Codeplex.ODataTFS.Model.Entities;

#endregion

namespace Codeplex.ODataTFS.Model.Serialization
{
	public class TFSBranchProxy : TFSBaseProxy
	{
		public TFSBranchProxy(Uri uri, ICredentials credentials)
			: base(uri, credentials)
		{
		}

		public Branch GetBranch(string path)
		{
			var versionControlServer = TfsConnection.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>();

			var identifier = new Microsoft.TeamFoundation.VersionControl.Client.ItemIdentifier(path);
			return versionControlServer.QueryBranchObjects(identifier, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None)
				.Where(b => !b.Properties.RootItem.IsDeleted)
				.Select(b => b.ToModel()).SingleOrDefault();
		}

		public IEnumerable<Branch> GetBranchesByProjectCollection()
		{
			var key = GetBranchesByProjectCollectionKey();

			if (Cache[key] == null)
			{
				Cache[key] = RequestBranchesByProjectCollection();
			}

			return (IEnumerable<Branch>) Cache[key];
		}

		public IEnumerable<Branch> GetBranchesByProject(string projectName)
		{
			var key = GetBranchesByProjectKey(projectName);

			if (Cache[key] == null)
			{
				Cache[key] = RequestBranchesByProject(projectName);
			}

			return (IEnumerable<Branch>) Cache[key];
		}

		private IEnumerable<Branch> RequestBranchesByProjectCollection()
		{
			var versionControlServer = TfsConnection.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>();
			var rootObjects = versionControlServer.QueryRootBranchObjects(Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None);

			return rootObjects.SelectMany(r => versionControlServer
													.QueryBranchObjects(r.Properties.RootItem, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.Full)
													.Where(b => !b.Properties.RootItem.IsDeleted)
													.Select(b => b.ToModel())).ToArray();
		}

		private IEnumerable<Branch> RequestBranchesByProject(string projectName)
		{
			var versionControlServer = TfsConnection.GetService<Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer>();
			var rootObjects = versionControlServer.QueryRootBranchObjects(Microsoft.TeamFoundation.VersionControl.Client.RecursionType.None);
			var projectPath = string.Format(CultureInfo.InvariantCulture, "$/{0}/", projectName);

			return rootObjects.SelectMany(r => versionControlServer
													.QueryBranchObjects(r.Properties.RootItem, Microsoft.TeamFoundation.VersionControl.Client.RecursionType.Full)
													.Where(b => !b.Properties.RootItem.IsDeleted && b.Properties.RootItem.Item.StartsWith(projectPath, StringComparison.OrdinalIgnoreCase))
													.Select(b => b.ToModel())).ToArray();
		}

		private string GetBranchesByProjectCollectionKey()
		{
			return "TFSBranchProxy.GetBranchesByProjectCollection";
		}

		private string GetBranchesByProjectKey(string projectName)
		{
			return string.Format(CultureInfo.InvariantCulture, "TFSBranchProxy.GetBranchesByProject_{0}", projectName);
		}
	}
}
